package com.example.service.impl;

import com.example.entity.Category;
import com.example.entity.Favorite;
import com.example.entity.User;
import com.example.entity.Video;
import com.example.dao.VideoDao;
import com.example.feignclients.CategoryClients;
import com.example.feignclients.UserClients;
import com.example.service.VideoService;
import com.example.utils.JSONUtils;
import com.example.utils.RedisPrefix;
import com.example.vo.VideoDetailVO;
import com.example.vo.VideoVO;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageImpl;
import org.springframework.data.domain.PageRequest;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.ObjectUtils;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * 视频(Video)表服务实现类
 *
 * @author makejava
 * @since 2022-03-04 16:07:47
 */
@Service("videoService")
@Slf4j
@Transactional
public class VideoServiceImpl implements VideoService {
    @Resource
    private VideoDao videoDao;

    @Autowired
    private RabbitTemplate rabbitTemplate;
    @Autowired
    private UserClients userClients;
    @Autowired
    private CategoryClients categoryClients;
    @Autowired
    private StringRedisTemplate stringRedisTemplate;

    @Autowired
    private RedisTemplate redisTemplate;

    /**
     * 通过ID查询单条数据
     *
     * @param id 主键
     * @return 实例对象
     */
    @Override
    public VideoVO queryById(Integer id){
        return getVideoVO(this.videoDao.queryById(id));
    }

    /**
     * 分页查询
     *
     * @param video 筛选条件
     * @param pageRequest      分页对象
     * @return 查询结果
     */
    @Override
    public Page<Video> queryByPage(Video video, PageRequest pageRequest) {
        long total = this.videoDao.count(video);
        return new PageImpl<>(this.videoDao.queryAllByLimit(video, pageRequest), pageRequest, total);
    }

    /**
     * 新增数据
     *
     * @param video 实例对象
     * @return 实例对象
     */
    @Override
    public Video insert(Video video) throws JsonProcessingException {
        video.setCreatedAt(new Date());
        video.setUpdatedAt(new Date());
        this.videoDao.insert(video);
        rabbitTemplate.convertAndSend("videos","",new ObjectMapper().writeValueAsString(getVideoVO(video)));
        return video;
    }

    /**
     * 修改数据
     *
     * @param video 实例对象
     * @return 实例对象
     */
    @Override
    public Video update(Video video) {
        this.videoDao.update(video);
        return this.videoDao.queryById(video.getId());
    }

    /**
     * 通过主键删除数据
     *
     * @param id 主键
     * @return 是否成功
     */
    @Override
    public boolean deleteById(Integer id) {
        return this.videoDao.deleteById(id) > 0;
    }

    @Override
    public List<VideoVO> queryAllByLimit(Integer page, Integer perPage) {
        page=(page-1)*perPage;
        //分页查询所有视频对象
        List<Video> videos=videoDao.queryAllByLimits(page,perPage);
        return getList(videos);

    }

    /**
     * 根据视频id查询视频
     * @param page
     * @param per_page
     * @param categoryId
     * @return
     */
    @Override
    public List<VideoVO> findAllByCategoryId(Integer page, Integer per_page, Integer categoryId) {
        int start= (page-1) * per_page;
        List<Video> videos = videoDao.findAllByCategoryId(start,per_page,categoryId);
        return getList(videos);
    }

    @Override
    public VideoDetailVO queryDetailById(String videoId, String token) {
        //根据id查询视频信息
        Video video = videoDao.queryById(Integer.valueOf(videoId));
        //新建videoVo对象
        VideoDetailVO videoDetailVO = new VideoDetailVO();
        //把video对象拷贝给videoVo对象
        BeanUtils.copyProperties(video,videoDetailVO);
        //调用类别服务
        Category category = categoryClients.category(video.getCategoryId());
        log.info("根据类别id查询到类别信息{}", JSONUtils.writeValueAsString(category));
        videoDetailVO.setCategory(category.getName());
        //调用用户客户端服务
        User user = userClients.user(video.getUid());
        log.info("根据用户id查询到的用户信息{}",JSONUtils.writeValueAsString(user));
        videoDetailVO.setUploader(user);
        //设置点赞数  初始默认为0
        videoDetailVO.setLikesCount(0);
        String likeCounts = stringRedisTemplate.opsForValue().get(RedisPrefix.VIDEO_LIKE_COUNT_PREFIX + video.getId());
        if (!ObjectUtils.isEmpty(likeCounts)){
            log.info("当前的点赞数为{}",likeCounts);
            videoDetailVO.setLikesCount(Integer.valueOf(likeCounts));
        }
        //设置播放数  初始值为0
        videoDetailVO.setPlaysCount(0);
        String playedCounts = stringRedisTemplate.opsForValue().get(RedisPrefix.VIDEO_PLAYED_COUNT_PREFIX + videoId);
        if (!ObjectUtils.isEmpty(playedCounts)){
            log.info("当前的播放次数是：{}",playedCounts);
            videoDetailVO.setPlaysCount(Integer.valueOf(playedCounts));
        }
        //设置当前yoghurt是否喜欢  不喜欢  收藏
        User o = (User) redisTemplate.opsForValue().get("session_" + token);
        if (!ObjectUtils.isEmpty(o)){
            //设置是否喜欢
            Boolean liked = stringRedisTemplate.opsForSet().isMember(RedisPrefix.USER_LIKE_PREFIX + o.getId(), videoId);
            videoDetailVO.setLiked(liked);
            //设置是否不喜欢
            Boolean disliked = stringRedisTemplate.opsForSet().isMember(RedisPrefix.USER_DISLIKE_PREFIX + o.getId(), videoId);
            videoDetailVO.setLiked(disliked);
            //设置是否收藏
            Favorite favorite = userClients.favorite(videoId, String.valueOf(o.getId()));
            //不为空则该用户已经收藏该视频
            if (ObjectUtils.isEmpty(favorite)){
                videoDetailVO.setFavorite(true);
            }
        }
        return videoDetailVO;
    }

    //将list video  转换为 list videoVos
    public List<VideoVO> getList(List<Video> videos){
        //创建videoVo集合
        ArrayList<VideoVO> videoVOS = new ArrayList<>();
        //对video进行遍历 在遍历过程中转换为videoVo
        videos.forEach(video -> {
                VideoVO videoVO = getVideoVO(video);
                videoVOS.add(videoVO); //添加视频

        });
        return videoVOS;
    }

    /**
     * 将video转换为videoVo
     * @param video
     * @return
     * @throws JsonProcessingException
     */
    public VideoVO getVideoVO(Video video){
        //创建videoVO
        VideoVO videoVO = new VideoVO();
        //复制属性
        BeanUtils.copyProperties(video,videoVO);
        //视频服务----->调用用户服务 根据用户id查询用户
        User user = userClients.user(video.getId());
        log.info("根据视频id查询的用户信息为{}",JSONUtils.writeValueAsString(user));
        videoVO.setUploader(user.getName());
        //视频服务----->调用视频类型服务 根据用户id查询类型
        Category category = categoryClients.category(video.getId());
        log.info("根据视频id查询的类型信息为{}",JSONUtils.writeValueAsString(category));
        videoVO.setCategory(category.getName());
        //设置点赞数量
        videoVO.setLikes(0);
        //String counts = stringRedisTemplate.opsForValue().get(RedisPrefix.VIDEO_LIKE_COUNT_PREFIX + video.getId());
        //if (!StringUtils.isEmpty(counts)) {
        //    log.info("当前视频点赞数量为: {}", counts);
        //    videoVO.setLikes(Integer.valueOf(counts));
        //}
        return videoVO;
    }
}
